//
// Created by wxd on 2025/7/19.
//

#pragma once

#include <iostream>
#include <vector>
#include <glm/glm.hpp>
#include <glm/trigonometric.hpp>
#include "../wrapper/log/Logger.h"
#include "../wrapper/monitor/GLDebug.hpp"
#include "../global/ChineseOutput.hpp"
#include "../global/EngineDataProperties.h"
#include "../application/app/Application.h"
#include "../glFramework/shader/Shader.h"
#include "../glFramework/constant/engine_layout.h"
#include "../glFramework/texture/Texture.h"
#include "../glFramework/utils/ResourceLoadUtils.h"
#include "../glFramework/bo/VBO.h"
#include "../glFramework/bo/VAO.h"
#include "../glFramework/constant/engine_uniform.h"
#include <memory>


/**
 * 手动测试mipmap， 测试方案：通过glImageTex2d生成不同级别的纹理时候，纹理数据不变，仅修改对应的level，width，height
 */

inline bool enableUniformTime = true;

inline float currentTime = 0.0f;

inline const char* vertexPath = "../demo/shader/_006/vertex_shader.glsl";
inline const char* fragmentPath = "../demo/shader/_006/fragment_shader.glsl";
inline const char* texPath = "../demo/texture/Spongebob.png";

inline void onResize(int width, int height) {
    glViewport(0, 0, width, height);
}

inline void onMouse(int button, int action, int mods) {
    // action = 1表示鼠标左键按下
    if (button == 0 && action == 1 && mods == 0) {
        enableUniformTime = false;
    } else {
        enableUniformTime = true;
    }

    std::cout << button << " " << action << " " << mods << std::endl;
}

inline void render() {
    ChineseOutput::init();
    EngineApp.initDefaultWindowConfig();
    EngineApp.setResizeCallback(onResize);
    EngineApp.setMouseCallback(onMouse);
    EngineApp.init();

    // raw data
    std::vector<float> vertices; // 顶点 + 纹理坐标

    vertices.push_back(0.0f);
    vertices.push_back(0.5f);
    vertices.push_back(0.0f);
    vertices.push_back(0.5f);
    vertices.push_back(1.0f);

    vertices.push_back(0.5f);
    vertices.push_back(-0.5f);
    vertices.push_back(0.0f);
    vertices.push_back(1.0f);
    vertices.push_back(0.0f);

    vertices.push_back(-0.5f);
    vertices.push_back(-0.5f);
    vertices.push_back(0.0f);
    vertices.push_back(0.0f);
    vertices.push_back(0.0f);

    // shader
    std::unique_ptr<Shader> shader = std::make_unique<Shader>(vertexPath, fragmentPath);

    // BO
    VAO vao;
    vao.bind();
    VBO vbo(vertices);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, fSize(5), reinterpret_cast<void *>(0));
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, fSize(5), reinterpret_cast<void *>(3 * sizeof(float)));
    glEnableVertexAttribArray(1);
    vao.unbind();

    // Texture
    Texture texture(texPath, true); // 用于测试mipmap的构造函数
    texture.setSamplerName(EngineUniform::uTexUnit);

    // render
    while (EngineApp.update()) {
        GL_CALL(glClear(GL_COLOR_BUFFER_BIT))

        shader->bindProgram();

        currentTime = static_cast<float>(glfwGetTime());

        // uniform相关数据
        shader->setUniform(EngineUniform::uTime,  0.5 * currentTime);
        shader->setUniform(EngineUniform::uW, static_cast<float>(EngineApp.getCurrentWindowWidth()));
        shader->setUniform(EngineUniform::uH, static_cast<float>(EngineApp.getCurrentWindowHeight()));
        shader->setUniform(texture.getSamplerName(), texture.getTextureUnit());

        vao.bind();
        GL_CALL(glDrawArrays(GL_TRIANGLES, 0, 3));
        vao.unbind();
        shader->unbindProgram();
    }

    vao.destroy();
    vbo.destroy();
    shader->deleteProgram();
    EngineApp.destroy();
}
